package com.easy.frame.gateway;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 自定义异常处理
 * <p>
 * 这里主要是为了拦截{@link NotFoundException}异常并返回503提示前端
 *
 * @author zzf
 * @date 2021/1/6 17:30
 */
@Slf4j
public class ExceptionHandler extends DefaultErrorWebExceptionHandler {

    /**
     * Create a new {@code DefaultErrorWebExceptionHandler} instance.
     *
     * @param errorAttributes    the error attributes
     * @param resourceProperties the resources configuration properties
     * @param serverProperties   the error configuration properties
     * @param applicationContext the current application context
     */
    public ExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, ServerProperties serverProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, serverProperties.getError(), applicationContext);
    }

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return super.getRoutingFunction(errorAttributes);
    }


    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
        if (throwable instanceof NotFoundException) {
            Mono<Void> result = super.handle(exchange, throwable);
            ServerHttpResponse httpResponse = exchange.getResponse();
            httpResponse.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
            return result;
        } else {
            return super.handle(exchange, throwable);
        }
    }
}
